package com.wu.ssm.spring.ioc;

import com.wu.ssm.spring.annotion.IAspect;
import com.wu.ssm.spring.annotion.MyPointCut;
import com.wu.ssm.aspect.AbsMethodAdvance;
import com.wu.ssm.aspect.TestAspect;
import com.wu.ssm.spring.utils.ClassUtil;
import com.wu.ssm.spring.utils.ReflectionUtil;

import java.lang.reflect.Method;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by wzf on 2018/11/27/027.
 */
public class ApplicationContextAOP {

    public static ConcurrentHashMap<String,Object> proxyBeanMap = new ConcurrentHashMap<>();


    static {
        initAopBeanMap("com.wu.ssm");
    }

    public static void initAopBeanMap(String basePath) {
        Set<Class<?>> classSet = ClassUtil.getClassSet(basePath);

        for (Class<?> clazz:classSet
             ) {
            if(clazz.isAnnotationPresent(IAspect.class)){
                Method [] methods =clazz.getDeclaredMethods();
                for (Method method:methods
                     ) {
                    // 找到切点
                    if(method.isAnnotationPresent(MyPointCut.class)){
                        // 拿到方法上的注解
                        MyPointCut pointCut = (MyPointCut) method.getAnnotations()[0];
                        String pointCutStr = pointCut.value();
                        String[] pointCutArr = pointCutStr.split("_");
                        // 被代理的类名
                        String className = pointCutArr[0];
                        // 被代理的方法名
                        String methodName = pointCutArr[1];
                        // 根据切点 创建被代理对象（直接调用Class.forName(className）得到的对象final不能被代理）
                        Object targetObj = ReflectionUtil.newInstance(className);
                        // 根据切面类创建代理者
                        AbsMethodAdvance proxyer = (AbsMethodAdvance)new TestAspect();
                        // 设置代理的方法
                        proxyer.setProxyMethodName(methodName);
                        // 生成目标对象的代理对象
                        Object object = proxyer.createProxyObject(targetObj);

                        if (object != null) {
                            proxyBeanMap.put(targetObj.getClass().getSimpleName().toLowerCase(), object);
                        }
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        ApplicationContextAOP applicationContextAOP = new ApplicationContextAOP();
    }
}
